using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Graphics; 

namespace Rogue
{
    public class Mission
    {
        protected Entity m_Giver;
        protected int m_labelId;
        protected string m_Desc;
        protected bool m_HasGiven;

        public Mission(Entity a_Giver) :
            this(a_Giver, "", "")
        {
            
        }

        public Mission(Entity a_Giver, string a_BeforeBump, string a_AfterBump)
        {
            m_Giver = a_Giver;
            m_Desc = a_AfterBump;
            m_HasGiven = false;

            m_DelayedCalls = new List<DelayedCallAndTime>();

            m_Giver.OnPlayerBump += new Entity.PlayerBumpHandler(m_Giver_OnPlayerBump);

            if (a_BeforeBump.Length > 0)
            {
                m_labelId = LabelHelper.Instance.Add(a_BeforeBump, m_Giver, 60.0f);
            }
        }

        public delegate void DelayedCall();
        class DelayedCallAndTime
        {
            public void Call() { m_ToCall(); }

            public event DelayedCall m_ToCall;
            public float m_Time;
        }
        List<DelayedCallAndTime> m_DelayedCalls;

        public void AddDelayedCall(float a_Dt, DelayedCall a_Call)
        {
            DelayedCallAndTime dcat = new DelayedCallAndTime();
            dcat.m_ToCall += a_Call;
            dcat.m_Time = a_Dt;
            m_DelayedCalls.Add(dcat);
        }

        public void Update(GameTime a_Time)
        {
            foreach (DelayedCallAndTime dcat in m_DelayedCalls)
            {
                dcat.m_Time -= (a_Time.ElapsedGameTime.Milliseconds / 1000.0f);

                if (dcat.m_Time < 0)
                {
                    dcat.Call();
                    m_DelayedCalls.Remove(dcat);
                    break;
                }
            }
        }

        void m_Giver_OnPlayerBump(Entity.BumpArgs e)
        {
            if (!m_HasGiven)
            {
                m_HasGiven = true;
                LabelHelper.Instance.Remove(m_labelId);

                if (m_Desc.Length > 0)
                {
                    m_labelId = LabelHelper.Instance.Add(m_Desc, m_Giver, Math.Max(1, m_Desc.Length / 10));
                    ConsoleWindow.Instance.AddMessage(String.Format("{0}: \"{1}\"", m_Giver.Name, m_Desc), Color.Yellow);
                }
            }            
        }

        public static void stairs_OnPlayerBump(Entity.BumpArgs e)
        {
            if (RogueGame.Instance.Map.CurrentDepth == 0)
            {
                ConsoleWindow.Instance.AddMessage("You enter a dungeon. It is awful.", Color.Yellow);
            }
            else if (RogueGame.Instance.Map.CurrentDepth == 2)  // last level..
            {
                ConsoleWindow.Instance.AddMessage("You descend to the deepest level. You hear the taunting of the goblin king...", Color.Yellow);
            }
            else if (RogueGame.Instance.Map.CurrentDepth == 3)  // slayed the goblin king
            {
                ConsoleWindow.Instance.AddMessage("You leave this awful place.", Color.Yellow);
            }
            else
            {
                ConsoleWindow.Instance.AddMessage(String.Format("You descend to a worse level ({0}).",
                                                        RogueGame.Instance.Map.CurrentDepth),
                                             Color.Yellow);
            }

            RogueGame.Instance.RunMapGenerator();
        }

        public void CleanupLabels()
        {
            LabelHelper.Instance.RemoveAll();
        }

        ~Mission()
        {
            CleanupLabels();
        }
    }
}
